package es.uned.etsii.si3.taller.servlets;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.opensymphony.xwork2.ActionSupport;

import es.uned.etsii.si3.taller.Cliente;
import es.uned.etsii.si3.taller.EmpleadoTaller;
import es.uned.etsii.si3.taller.FactoriaDAO;
import es.uned.etsii.si3.taller.FactoriaFunciones;
import es.uned.etsii.si3.taller.ParteTrabajo;
import es.uned.etsii.si3.taller.Reparacion;
import es.uned.etsii.si3.taller.Taller;
import es.uned.etsii.si3.taller.Trabajo;
import es.uned.etsii.si3.taller.Usuario;
import es.uned.etsii.si3.taller.Vehiculo;
import es.uned.etsii.si3.taller.misc.ProporcionaFuncionalidad;

public class PTVistosBuenos extends ActionSupport implements SessionAware {

	private static final long serialVersionUID = 1L;

	private 	Map<String, Object>		userSession;
	
	private		String					fechaFinString;
	public		String					getFechaFinString()							{ return this.fechaFinString; }
	public 		void					setFechaFinString(String s)					{ this.fechaFinString = s; }
	
	private 	ParteTrabajo			parteSeleccionado = null;
	public 		ParteTrabajo			getParteSeleccionado() 						{ return this.parteSeleccionado; }
	public 		void					setParteSeleccionado(ParteTrabajo pT) 		{ this.parteSeleccionado = pT; }

	private 	static int 				parteSeleccionadoID = -1;
	public 		int						getParteSeleccionadoID() 					{ return PTVistosBuenos.parteSeleccionadoID; }
	public 		void					setParteSeleccionadoID(int i) 				{ PTVistosBuenos.parteSeleccionadoID = i; }
	
	private 	Reparacion				reparacionSeleccionado = null;
	public 		Reparacion				getReparacionSeleccionado()					{ return this.reparacionSeleccionado; }
	public 		void					setReparacionSeleccionado(Reparacion r)		{ this.reparacionSeleccionado = r; }

	private 	static int 				reparacionSeleccionadoID = -1;
	public 		int						getReparacionSeleccionadoID() 				{ return PTVistosBuenos.reparacionSeleccionadoID; }
	public 		void					setReparacionSeleccionadoID(int i) 			{ PTVistosBuenos.reparacionSeleccionadoID = i; }

	private 	Trabajo					trabajoSeleccionado = null;
	public 		Trabajo					getTrabajoSeleccionado() 					{ return this.trabajoSeleccionado; }
	public 		void					setTrabajoSeleccionado(Trabajo t) 			{ this.trabajoSeleccionado = t; }
		
	private 	static int 				trabajoSeleccionadoID = -1;
	public 		int						getTrabajoSeleccionadoID()					{ return PTVistosBuenos.trabajoSeleccionadoID; }
	public 		void					setTrabajoSeleccionadoID(int i) 			{ PTVistosBuenos.trabajoSeleccionadoID = i; }

	private 	List<ParteTrabajo>		listaPartes;		
	public		List<ParteTrabajo>		getListaPartes() 							{ return this.listaPartes; }
	public 		void					setListaPartes(List<ParteTrabajo> l)		{ this.listaPartes = l; }
	
	private 	List<Reparacion> 		listaReparaciones = null;
	public 		List<Reparacion>		getListaReparaciones()						{ return this.listaReparaciones; }
	public 		void 					setListaReparaciones(List<Reparacion> l)	{ this.listaReparaciones = l; }

	private 	List<Trabajo>			listaTrabajos;
	public 		List<Trabajo>			getListaTrabajos()							{ return this.listaTrabajos; }
	public 		void					setListaTrabajos(List<Trabajo> l)			{ this.listaTrabajos = l; }
	
	/**
	 * Carga las reparaciones pendientes de visto bueno
	 * @return  actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_TALLER_PENDIENTE_VB)	
	public String pTCargarVB() throws SQLException {
		String res = SUCCESS;
		
		QueryBuilder<ParteTrabajo, Integer> parteQb = FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();
		Where<ParteTrabajo, Integer> wParteQb = parteQb.where();
		wParteQb.eq(ParteTrabajo.ID_TALLER_FIELD_NAME, this.getTallerSesionEmpleado());
		wParteQb.and().eq(ParteTrabajo.VISTOBUENO_FIELD_NAME, false);
			
		//parte-vehiculo
		QueryBuilder<Vehiculo, Integer> vehiculoQb = FactoriaDAO.getDao(Vehiculo.class).queryBuilder();
		QueryBuilder<ParteTrabajo, Integer> parJOINveh = FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();
		parJOINveh = parteQb.join(vehiculoQb);

		//usuario-cliente
		QueryBuilder<Usuario, Integer> usuarioQb = FactoriaDAO.getDao(Usuario.class).queryBuilder();
		QueryBuilder<Cliente, Integer> clienteQb = FactoriaDAO.getDao(Cliente.class).queryBuilder();
		QueryBuilder<Usuario, Integer> usuJOINcli = FactoriaDAO.getDao(Usuario.class).queryBuilder();
		usuJOINcli = usuarioQb.join(clienteQb);
			
		//(parte-vehiculo)-(usuario-cliente)
		QueryBuilder<ParteTrabajo, Integer> parJOINusu = FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();
		parJOINusu = parJOINveh.join(usuJOINcli);
			
		List<ParteTrabajo> lPar = parJOINusu.query();
		List<ParteTrabajo> lSal = new ArrayList<ParteTrabajo>();		
		
		QueryBuilder<Reparacion, Integer> reparacionQb;
		Where<Reparacion, Integer> wReparacionQb;
		List<Reparacion> lRep = new ArrayList<Reparacion>();	
			
		for (int i=0; i<lPar.size(); i++) {
			reparacionQb = FactoriaDAO.getDao(Reparacion.class).queryBuilder();
			wReparacionQb = reparacionQb.where();			
			wReparacionQb.eq(Reparacion.ID_PARTETRABAJO_FIELD_NAME, lPar.get(i).getId());
			wReparacionQb.and().eq(Reparacion.VISTOBUENO_FIELD_NAME, true);
			lRep = reparacionQb.query();
			if ( lRep.size() > 0 ) { //SI existen reparaciones con VB=true
				reparacionQb = FactoriaDAO.getDao(Reparacion.class).queryBuilder();
				wReparacionQb = reparacionQb.where();			
				wReparacionQb.eq(Reparacion.ID_PARTETRABAJO_FIELD_NAME, lPar.get(i).getId());
				wReparacionQb.and().eq(Reparacion.VISTOBUENO_FIELD_NAME, false);
				lRep = reparacionQb.query();
				if ( lRep.size() < 1 ) { //NO existen reparaciones con VB=false
					lSal.add(lPar.get(i));
				}
			}
		}
		
		this.setListaPartes(lSal);
		return res;
	}
	
	/**
	 * Permite dar el visto bueno a una reparación
	 * @return  actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_TALLER_PENDIENTE_VB)	
	public String pTDarVB() throws SQLException {
		String res = SUCCESS;
		this.setParteSeleccionadoID(this.getParteSeleccionadoID());
		//this.recuperarParteSeleccionado();
		this.setParteSeleccionado(FactoriaDAO.recuperar(ParteTrabajo.class, this.getParteSeleccionadoID()));		
		if ( this.getFechaFinString().isEmpty() ) {
			addActionError("La Fecha es obligatoria. Y en formato dd/mm/aa.");
			res = ERROR;
		} else {			
			SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy");
			this.parteSeleccionado.setTaller(this.getTallerSesionEmpleado());						
			try {
				this.parteSeleccionado.setFechaFin(df.parse(this.getFechaFinString()));
			} catch (ParseException e) {
				addActionError("Formato de la fecha erróneo");
				res = ERROR;
			}
			this.parteSeleccionado.setVistoBueno(true);
			this.parteSeleccionado.setAvisado(false);
			this.parteSeleccionado.update();
		}
		return res;
	}
	
	/**
	 * Da detalles de la reparación
	 * @return  actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_TALLER_PENDIENTE_VB)	
	public String pTDetallesVB() throws SQLException {
		String res = SUCCESS;
		this.setParteSeleccionadoID(this.getParteSeleccionadoID());
		//this.recuperarParteSeleccionado();
		this.setParteSeleccionado(FactoriaDAO.recuperar(ParteTrabajo.class, this.getParteSeleccionadoID()));
		this.parteSeleccionado.setTaller(this.getTallerSesionEmpleado());
		QueryBuilder<ParteTrabajo, Integer> parteQb = FactoriaDAO.getDao(ParteTrabajo.class).queryBuilder();
		Where<ParteTrabajo, Integer> wParteQb = parteQb.where();
		wParteQb.eq(ParteTrabajo.ID_FIELD_NAME, this.getParteSeleccionadoID());
			
		QueryBuilder<Reparacion, Integer> reparacionQb = FactoriaDAO.getDao(Reparacion.class).queryBuilder();
		QueryBuilder<Trabajo, Integer> trabajoQb = FactoriaDAO.getDao(Trabajo.class).queryBuilder();
		List<Trabajo> lista = trabajoQb.join(reparacionQb.join(parteQb)).query();
						
		//Date hoy = new Date();
		//this.setFechaFinString((String)hoy);
		this.setListaTrabajos(lista);
		return res;
	}

	/**
	 * Marca una reparación como no aceptada
	 * @return  actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_TALLER_PENDIENTE_VB)	
	public String pTNOAceptarVB() throws SQLException {
		String res = SUCCESS;
		this.setTrabajoSeleccionadoID(this.getTrabajoSeleccionadoID());
		this.setTrabajoSeleccionado(FactoriaDAO.recuperar(Trabajo.class, this.getTrabajoSeleccionadoID()));
		//rechaza el trabajo
		this.trabajoSeleccionado.setVistoBuenoJS(false);
		this.trabajoSeleccionado.setFechaFin(null);
		this.trabajoSeleccionado.update();
		//rechaza la reparacion
		this.setReparacionSeleccionado(this.getTrabajoSeleccionado().getReparacion());
		this.setReparacionSeleccionadoID(this.getReparacionSeleccionado().getId());
		this.getReparacionSeleccionado().setVistoBueno(false);
		this.getReparacionSeleccionado().setFechaFin(null);
		this.reparacionSeleccionado.update();
		return res;
	}

	
	

	private Taller getTallerSesionEmpleado() {
		Taller res = null;
		Usuario uS = (Usuario) userSession.get("usuario");
		QueryBuilder<EmpleadoTaller, Integer> eTQb;
		try {
			eTQb = FactoriaDAO.getDao(EmpleadoTaller.class).queryBuilder();
			Where<EmpleadoTaller, Integer> wETQb = eTQb.where();			
			wETQb.eq(EmpleadoTaller.ID_USUARIO_FIELD_NAME, uS.getId());			
			List<EmpleadoTaller> lista = wETQb.query();
			res = lista.get(0).getTaller();
		} catch (SQLException e) {
			addActionError("Error al buscar taller: " + e);
		}			
		return res;
	}

	
	
	@Override
	public void setSession(Map<String, Object> session) {
		userSession = session;		
	}

}
